
#ifndef _Ring_QUEUE_HPP_
#define _Ring_QUEUE_HPP_

#include <iostream>
#include <vector>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include "sem.hpp"
#include "mutex.hpp"
#include "task.hpp"

const int max_value = 5;

template <class T>
class RingQueue
{
private:
    std::vector<T> _ringQueue;
    int _num;   //总容量
    int _cIndex;//消费者下标
    int _pIndex;//生产者下标
    Sem _spaceSem;//空间资源
    Sem _dataSem; //数据资源
    Mutex _cMutex;//消费者们的互斥锁
    Mutex _pMutex;//生产者们的互斥锁
public:
    RingQueue(int value = max_value)
    :_ringQueue(max_value)
    ,_num(max_value)
    ,_cIndex(0),_pIndex(0)
    ,_spaceSem(value),_dataSem(0)
    {}

    ~RingQueue(){}

    void Push(const T& x)
    {
         _spaceSem.P();//空间资源减一

        _pMutex.lock();//生产者们竞争一把锁

        _ringQueue[_pIndex++] = x;
        _pIndex %= _num;

        _pMutex.unlock();

        _dataSem.V();//数据资源加一

    }

    void Pop(T& ret)
    {
        _dataSem.P();
        _cMutex.lock();//消费者们竞争一把锁

        ret = _ringQueue[_cIndex++];
        _cIndex %= _num;

        _cMutex.unlock();
        _spaceSem.V();

    }
};


#endif